package gogoqiu.plugin;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Date;

import org.gradle.api.logging.Logger;
import org.gradle.api.tasks.bundling.Jar;
import org.gradle.api.Project;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;

/*
 * translate from "dev-tools/src/main.ts"
 * prepack 
 */
public class VersionUpdater {
    Logger logger;

    /*
    // 参考nodejs的package.json
     */
    public static class Package{
        String version;
        String group;
        String name;
        String description;

        public String getName() {
            return name;
        }

        public String getDescription() {
            return description;
        }

        public String getGroup() {
            return group;
        }

        public String getVersion() {
            return version;
        }
    }

    public VersionUpdater( Logger logger ){
        this.logger = logger;
    }
    
    /*
     * dev-tools.json
     * 给出变量，修改文件
     */
    public void updateVersion( Project project ) throws IOException, IllegalArgumentException {
        this.logger.info("---UpdateVersion---");
        //Logger logger = project.getLogger();        
        String currentDir = System.getProperty("user.dir");
        Path path = Paths.get( currentDir, "package.json" );

        //File packageJson = new File("package.json");

        //logger.lifecycle("当前工作目录: {}", currentDir);
        //logger.lifecycle("package.json 绝对路径: {}", packageJson.getAbsolutePath());
        //logger.lifecycle("package.json 是否存在: {}", packageJson.exists());
        //File file = new File("package.json");
        if( Files.exists(path) ){
            byte[] bytes = Files.readAllBytes(path);
            String content = new String(bytes, StandardCharsets.UTF_8);
            Gson gson = new Gson();
            Package p = gson.fromJson( content, new TypeToken<Package>() { }.getType() );
            if( p.version==null || p.name==null || p.group==null ||p.description==null ){            
                project.getLogger().info("package.json: version/name/group/description is necessary");
                throw new IllegalArgumentException("package.json: version/name/group/description is necessary");
            }
            String version = p.version;
            p.version = VersionUpdaterUtils.updateVersion(version);
            project.getLogger().info( String.format("版本更新到:%s=>%s", version, p.version) );
            this.injectBuild(project, p);

            Gson builder = new GsonBuilder()
                .setPrettyPrinting() // 格式化输出
                .create();
            String jsonString = builder.toJson(p);
            Files.write(path, jsonString.getBytes("UTF-8"), StandardOpenOption.CREATE,    // 不存在则创建
                    StandardOpenOption.TRUNCATE_EXISTING,  // 存在则截断（覆盖）
                    StandardOpenOption.WRITE );       // 写入模式
            buildJavaFile( p.version );
        }else{
            throw new IOException( String.format( "文件找不到: %s/%s", currentDir, path));
        }        
    }

    /*
     * archivesBaseName就是最后maven publish的artifactId
     * 在 Gradle 中，archivesBaseName 通常会作为 Maven 发布时 artifactId 的默认值
     * ext的设置与访问
     * 访问:
     * 
     * apply的时候就配置setVersion
     * public void apply(Project project) { project.setGroup( "abc" );} build.gradle: 先apply plugin: xxx;然后group="bcd", 最后group是啥
     * 如何通过public void apply(Project project) {修改jar {
            archiveBaseName = 'base'  
        }里archiveBaseName
       如果插件中设置的值需要被 build.gradle 中的后续配置覆盖，可以保持上述写法（因为脚本中后执行的配置会覆盖插件的设置）。
     */
    void injectBuild( Project project, Package p ){
        //
        project.setVersion( p.version );
        project.setGroup( p.group );
        project.setDescription( p.description );
        //artifactId
        //project.getExtensions().getExtraProperties().set("artifactId", p.name);
        //project.getLogger().debug(null);
        //project.getExtensions();
        /*
         * project name: usePlugin
         * ...
         * set project name: demo
         * package.json
         *  name
         */        
        project.getLogger().info( String.format("project name: %s", project.getName()) );
        // 获取或创建 jar 任务，并配置其 archiveBaseName
        project.afterEvaluate(pro -> {
            pro.getTasks().withType(Jar.class, jarTask -> {
                // 设置 jar 任务的 archiveBaseName
                //jarTask.setArchiveBaseName("base");
                // 注意：这里是通过 getArchiveBaseName() 获取属性对象，再调用 set 方法
                project.getLogger().info( String.format("set project name: %s", p.name) );
                jarTask.getArchiveBaseName().set( p.name );
            });
        });
        Package packageDef = project.getExtensions().create("packageDef", Package.class);
        packageDef.description = p.description;
        packageDef.name = p.name;
        packageDef.version = p.version;
        packageDef.group = p.group;
    }

    /*
    // 把编译时间编入java
     */
    void buildJavaFile( String version ) throws IOException {
        this.logger.info("---buildJavaFile---");        
        /*
        String base = """
        package gogoqiu;
        public class Build{
            public static String version = \"%s\";
            public static String buildTime = \"%s\";
        }        
        """;
        */
        String base = 
    "package gogoqiu;\n" +
    "public class Build{\n" +
    "    public static String version = \"%s\";\n" +
    "    public static String buildTime = \"%s\";\n" +
    "}";
        // 获取当前时间（本地时间）
        LocalDateTime now = LocalDateTime.now();
        
        // 定义格式化器，指定格式为 yy-MM-dd hh:mm:ss
        // 注意：hh 表示 12小时制，HH 表示 24小时制
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd hh:mm:ss");
        
        // 格式化时间
        String formattedTime = now.format(formatter);
        
        String content = String.format( base, version, formattedTime );
        String currentDir = System.getProperty("user.dir");
        Path path = Paths.get( currentDir, "src", "main", "java", "gogoqiu", "Build.java" );

        Files.write(path, content.getBytes("UTF-8"), StandardOpenOption.CREATE,    // 不存在则创建
                    StandardOpenOption.TRUNCATE_EXISTING,  // 存在则截断（覆盖）
                    StandardOpenOption.WRITE );       // 写入模式
    }
}
